/**
 *
 *
 * @export
 * @class Vue
 *  Vue
 *  1.data->data()->Vm.$data->reactive(响应式)->vm.xxx
 *      get vm[key] ->vm.$data[key]
 *      set vm[key] ->vm.$data[key] = newValue
 *          ?-> updateComputedProp ->value
 *          ?->updateWatchProp->callback
 *
 *  2.computed->props->{
 *      value->get->value
 *      get->method
 *      dep->[a,b] 收集依赖 this.xxxx  this.cccc this.a  this.b
 *      a,b有变化从新执行method return 值重新更新
 *
 *  }
 *  3.watch->props->fn->data set ->call fn
 *
 *
 *
 */
import { reactive } from "./reactive";
import { Computed } from "./Computed";
import { Watcher } from "./Watcher";
class Vue {
  constructor(options) {
    // console.log("vue vue 22 33", options);
    const { data, computed, watch } = options;
    this.$data = data(); //挂载实列
    this.init(this, computed, watch);
  }
  init(vm, computed, watch) {
    this.initData(vm);
    const computedIns = this.initComputed(vm, computed);
    const watcherIns = this.initWatcher(vm, watch);
    this.$computed = computedIns.update.bind(computedIns);
    this.$watch = watcherIns.invoke.bind(watcherIns);
  }

  initData(vm) {
    reactive(
      vm,
      (key, value) => {
        // console.log(key, value, "get 回调函数");
      },
      (key, newValue, oldValue) => {
        console.log("set 回调函数 ", key);
        this.$watch(key, newValue, oldValue);
        this.$computed(key, this.$watch);
      }
    );
  }
  initComputed(vm, computed) {
    // 枚举computed->增加computedData
    // 返回实列 ->实例里有update方法 ->更新computedData的value
    const computedIns = new Computed();
    for (let key in computed) {
      computedIns.addComputed(vm, computed, key);
    }
    // console.log(computedIns.computedData);
    this.computedIns = computedIns.computedData; //后面可以用来观察
    return computedIns;
  }
  initWatcher(vm, watch) {
    // 枚举watcher->增加侦听器
    // 返回实列 ->实例里有调用watch的方法 ->执行侦听器

    const watcherIns = new Watcher();
    for (let key in watch) {
      watcherIns.addWatcher(vm, watch, key);
    }
    // console.log(watcherIns.computedData);
    this.watcherIns = watcherIns.watchers; //后面可以用来观察
    return watcherIns;
  }
}
export default Vue;
